Turn your spaghetti code into ravioli with JavaScript modulesjerryorr
JavaScript is the language that powers the interactive web of the future. But as our web applications become larger and more complex, we begin to strain the old paradigm of throwing a bunch of JavaScript functions into a few files. Complex dependencies, tight coupling, and global state can turn our code into a huge plate of spaghetti. Though browsers do not natively support JavaScript modules, there are many tools that can help us to write clean, modular JavaScript.
In this session, we will explore the benefits of writing modular JavaScript. We will also take a deep dive into specific JavaScript module systems, such as Browserify, RequireJS, and the module standards that are coming in ES6.
Turn your spaghetti code into ravioli with JavaScript modulesjerryorr
JavaScript is the language that powers the interactive web of the future. But as our web applications become larger and more complex, we begin to strain the old paradigm of throwing a bunch of JavaScript functions into a few files. Complex dependencies, tight coupling, and global state can turn our code into a huge plate of spaghetti. Though browsers do not natively support JavaScript modules, there are many tools that can help us to write clean, modular JavaScript.
In this session, we will explore the benefits of writing modular JavaScript. We will also take a deep dive into specific JavaScript module systems, such as Browserify, RequireJS, and the module standards that are coming in ES6.
Server-Side Push: Comet, Web Sockets come of age (OSCON 2013)Brian Sam-Bodden
Server-side browser push technologies have been around for a while in one way or another, ranging from from crude browser polling to Flash enabled frameworks. In this session you’ll get a code-driven walk-through on the evolution and mechanics of server-push technologies, including:
Server streaming
Polling and long Polling
Comet
Web Sockets
Mobile Patrons: Better Services on the Go (For Techie)Vincci Kwong
Several mobile friendly initiatives which improve mobile user’s experience with library resources will be discussed. These initiatives include creation of a mobile library website, development of mobile friendly authentication user interface, implementation of a computer availability mobile page and offering of texting reference service.
The Web beyond "usernames & passwords" (OSDC12)Francois Marier
Identity systems on the Web are a bit of a mess. Surely in 2012, we would have something else than usernames and passwords for logging into websites. A solution that doesn't require trusting a central authority with a privacy policy that can change at a whim.
It turns out that solving the general identity problem is very hard. Some of these solutions require complicated redirections, an overwhelming amount of jargon and lots of verbose XML. The technology has been around for a long time, but implementing it properly (and safely) is often incredibly difficult. It's a lot to ask of the millions of part-time developers out there that are building sites out of some quick HTML, a MySQL database and some PHP Code samples.
This talk will explore the challenges of the existing Web identity solutions and introduce the choices that we made during the development of Persona, a new Open Source federated identity solution from Mozilla, designed and built to respect user privacy.
Building Persona: federated and privacy-sensitive identity for the Web (Open ...Francois Marier
This talk explores the challenges of the existing Web identity solutions and introduce the choices that were made during the development of Persona (formerly BrowserID), a new Open Source federated identity solution from Mozilla, designed and built to respect user privacy.
A brief summary of our first month experience using Mojolicious: what worked and what didn't work.
Taken from the Oslo Perl Mongers talk given October 5th, 2011
Passwords suck, but centralized proprietary services are not the answerFrancois Marier
Passwords are a big problem online and a lot of websites have turned to centralized services to handle logins for them. It's a disturbing trend from a privacy/surveillance point of view, but from a software freedom point of view, it's also turning these proprietary services into core dependencies.
That's why Mozilla is building Persona, a new federated and cross-browser system which makes identity a standard part of the browser. It's simple, privacy-sensitive and entirely free software.
Building Single Page Application (SPA) with Symfony2 and AngularJSAntonio Peric-Mazar
Forget about classic website where UX is not so important. We are living in time where usability is one of the important thing if you are building some business client oriented web service. How to connect Symfony2 as backend and AngularJS as frontend solution? What are best practices? What are disadvantageous? How to take best from both worlds? These are topics I will cover in my talk with real examples.
Building Persona: federated and privacy-sensitive identity for the Web (LCA 2...Francois Marier
This talk explores the challenges of the existing Web identity solutions and introduce the choices that were made during the development of Persona (formerly BrowserID), a new Open Source federated identity solution from Mozilla, designed and built to respect user privacy.
Server-Side Push: Comet, Web Sockets come of age (OSCON 2013)Brian Sam-Bodden
Server-side browser push technologies have been around for a while in one way or another, ranging from from crude browser polling to Flash enabled frameworks. In this session you’ll get a code-driven walk-through on the evolution and mechanics of server-push technologies, including:
Server streaming
Polling and long Polling
Comet
Web Sockets
Mobile Patrons: Better Services on the Go (For Techie)Vincci Kwong
Several mobile friendly initiatives which improve mobile user’s experience with library resources will be discussed. These initiatives include creation of a mobile library website, development of mobile friendly authentication user interface, implementation of a computer availability mobile page and offering of texting reference service.
The Web beyond "usernames & passwords" (OSDC12)Francois Marier
Identity systems on the Web are a bit of a mess. Surely in 2012, we would have something else than usernames and passwords for logging into websites. A solution that doesn't require trusting a central authority with a privacy policy that can change at a whim.
It turns out that solving the general identity problem is very hard. Some of these solutions require complicated redirections, an overwhelming amount of jargon and lots of verbose XML. The technology has been around for a long time, but implementing it properly (and safely) is often incredibly difficult. It's a lot to ask of the millions of part-time developers out there that are building sites out of some quick HTML, a MySQL database and some PHP Code samples.
This talk will explore the challenges of the existing Web identity solutions and introduce the choices that we made during the development of Persona, a new Open Source federated identity solution from Mozilla, designed and built to respect user privacy.
Building Persona: federated and privacy-sensitive identity for the Web (Open ...Francois Marier
This talk explores the challenges of the existing Web identity solutions and introduce the choices that were made during the development of Persona (formerly BrowserID), a new Open Source federated identity solution from Mozilla, designed and built to respect user privacy.
A brief summary of our first month experience using Mojolicious: what worked and what didn't work.
Taken from the Oslo Perl Mongers talk given October 5th, 2011
Passwords suck, but centralized proprietary services are not the answerFrancois Marier
Passwords are a big problem online and a lot of websites have turned to centralized services to handle logins for them. It's a disturbing trend from a privacy/surveillance point of view, but from a software freedom point of view, it's also turning these proprietary services into core dependencies.
That's why Mozilla is building Persona, a new federated and cross-browser system which makes identity a standard part of the browser. It's simple, privacy-sensitive and entirely free software.
Building Single Page Application (SPA) with Symfony2 and AngularJSAntonio Peric-Mazar
Forget about classic website where UX is not so important. We are living in time where usability is one of the important thing if you are building some business client oriented web service. How to connect Symfony2 as backend and AngularJS as frontend solution? What are best practices? What are disadvantageous? How to take best from both worlds? These are topics I will cover in my talk with real examples.
Building Persona: federated and privacy-sensitive identity for the Web (LCA 2...Francois Marier
This talk explores the challenges of the existing Web identity solutions and introduce the choices that were made during the development of Persona (formerly BrowserID), a new Open Source federated identity solution from Mozilla, designed and built to respect user privacy.
O grandiosismo dos loucos - Agile Brazil 2011, Cecilia Fernandes e Guilherme ...Guilherme Silveira
Uma discussão sobre alguns raros posts que apresentam soluções do tipo "o que temos hoje é o suficiente ou o melhor para sempre"
O ponto é discutir que não podemos parar de aprender, inovar, e tentar mudar o mercado para melhor.
Diversas praticas que podemos adotar para minimizar o tempo minimo para entrega de um produto novo no mercado e a experiencia com um produto especifico.
Começando com integração contínua, seguimos todos os passos até deploy contínuo. Tudo o que você precisa saber para, no decorrer de alguns meses, sair de um sistema de deploy bagunçado para um automatizado.
Palestra apresentada no Mare de Agilidade 2010 em BH por Guilherme Silveira, da Caelum.
Slides da aula aberta sobre REST da Caelum. Onde Jim Webber da TW apresentou motivos financeiros para voce passar a usar a web como infraestrutura. Guilherme Silveira mostrou como fazer isso.
48. resttrips.com: sharing a trip
flight = Client.at('http://resttrips.com/f/574XR4').get();
confirmation = flight.getLink("payment").
patch(cardInformation, value/2);
// send the payment link to another part of the web
flight = Client.at('http://resttrips.com/f/574XR4').get();
confirmation = flight.getLink("payment").
patch(cardInformation, value/2);
49. resttrips.com: sharing a trip
flight = Client.at('http://resttrips.com/f/574XR4').get();
confirmation = flight.getLink("payment").
patch(cardInformation, value/2);
// send the payment link to another part of the web
flight = Client.at('http://resttrips.com/f/574XR4').get();
confirmation = flight.getLink("payment").
patch(cardInformation, value/2);
50. resttrips.com: sharing a trip
flight = Client.at('http://resttrips.com/f/574XR4').get();
confirmation = flight.getLink("payment").
patch(cardInformation, value/2);
// send the payment link to another part of the web
flight = Client.at('http://resttrips.com/f/574XR4').get();
confirmation = flight.getLink("payment").
patch(cardInformation, value/2);
51. resttrips.com: sharing a trip
flight = Client.at('http://resttrips.com/f/574XR4').get();
confirmation = flight.getLink("payment").
patch(cardInformation, value/2);
// send the payment link to another part of the web
flight = Client.at('http://resttrips.com/f/574XR4').get();
confirmation = flight.getLink("payment").
patch(cardInformation, value/2);
52. calendar: integrating my systems
myself = Client.at('http://users.calendar.com')
.with(auth).get();
myself.link("calendar").patch(flight.link("self"));
53. calendar: integrating my systems
myself = Client.at('http://users.calendar.com')
.with(auth).get();
myself.link("calendar").patch(flight.link("self"));
56. so what?
Any update on the flight ==> reflects here
Any update on the hotel ==> reflects here
Any update on the meeting ==> reflects here
57. so what?
r at e!
i nt eg
us e,
ju st
o n ’t
d
Any update on the flight ==> reflects here
Any update on the hotel ==> reflects here
Any update on the meeting ==> reflects here
59. so what? that was just keeping an URI.
Remove ==> Cancels the flight
Remove ==> Cancels the reservation
Remove ==> Emails your coworkers
60. so what? that was just keeping an URI.
ro l!
co nt
a li ze
en tr
no tc
do
Remove ==> Cancels the flight
Remove ==> Cancels the reservation
Remove ==> Emails your coworkers
61. integration over the web
INTEGRATION is DECENTRALIZING the CONTROL
delegating to multiple agents
distributed systems
63. so what? that was just keeping an URI.
Remove ==> Cancels the flight
Remove ==> Cancels the reservation
Remove ==> Emails your coworkers
64. so what? that was just keeping an URI.
a t?
fo rm
hi ch
bu tw
Remove ==> Cancels the flight
Remove ==> Cancels the reservation
Remove ==> Emails your coworkers
65. mas qual o formato do
pagamento ou calendário?
98. Server Maturity
1 uri, 1 http verb
/services.do?action=install&...
99. Server Maturity
1 uri, 1 http verb
/services.do?action=install&...
@Path("/services")
public class Services {
@GET
public Response services(
@QueryParam("action") String action) {
ServiceFactory factory = new ServiceFactory();
Service service = factory.getServiceFor(action);
return service.execute();
}
}
100. Server Maturity
1 uri, 1 http verb
public class InstallService {
public Response execute() {
return Response.ok()
.type("application/xml")
.entity("<service>...</service>")
.build();
}
}
108. Server Maturity
Multiple uris, 1 http verb
/install?...
@Path("/services")
public class Services {
@GET @Path("install")
public Response install() {
return new InstallService().execute();
}
@GET @Path("uninstall")
public Response uninstall() {
return new UninstallService().execute();
}
116. Vraptor
vraptor.org/en
@Resource
public class SoftwareResource {
public void install() {
Software software = SoftwareRepository.register
(software);
response.created(software);
}
public void uninstall() {
response.deleted(software);
}
}
117. JAX-RS
@Path("/softwares")
public class SoftwareResource {
@POST @Consumes("application/xml")
public Response install(Software software) {
software = SoftwareRepository.register(software);
long id = software.getId();
URI uri = UriBuilder.fromPath("/softwares/" + id)
.build();
software.install();
return Response.created(uri).build();
}
118. JAX-RS
@DELETE @Path("{id}")
public Response uninstall(@PathParam("id") Long id) {
Software software = SoftwareRepository.retrieve(id);
software.uninstall();
return Response.ok().build();
}
132. Cloud API
GET /user/15 retrieves an user
follow GET machines accesses its machines
133. Cloud API
GET /user/15 retrieves an user
follow GET machines accesses its machines
follow POST self installs a new machine
134. Cloud API
GET /user/15 retrieves an user
follow GET machines accesses its machines
follow POST self installs a new machine
follow POST payment pay for it
135. retrieves an user
$ curl http://localhost:9998/user/574 -i
HTTP/1.1 200 OK
...
144. @XmlRootElement
@XmlType(propOrder= {"id", "host", "softwares", "links"})
public class Machine {
private final all variables here;
@XmlElement(name="link", namespace="http://www.w3.org/2005/Atom")
public List<Link> getLinks() {
return Arrays.asList(
Link.to("/machines/" + getId(), "self"),
Link.to("/machines/" + getId() + "/softwares", "softwares")
);
}
@XmlElementWrapper(name="softwares")
@XmlElement(name="software")
public List<Software> getSoftwares() {
return softwares;
}
public void install(Software software) {
getSoftwares().add(software);
}
public void uninstall(Software software) {
getSoftwares().remove(software);
}
} Machine.java
145. @XmlRootElement
@XmlType(propOrder= {"id", "host", "softwares", "links"})
public class Machine {
private final all variables here;
@XmlElement(name="link", namespace="http://www.w3.org/2005/Atom")
public List<Link> getLinks() {
return Arrays.asList(
Link.to("/machines/" + getId(), "self"),
Link.to("/machines/" + getId() + "/softwares", "softwares")
);
}
@XmlElementWrapper(name="softwares")
@XmlElement(name="software")
public List<Software> getSoftwares() {
return softwares;
}
public void install(Software software) {
getSoftwares().add(software);
}
public void uninstall(Software software) {
getSoftwares().remove(software);
}
} Machine.java
146. @Path("/machines")
public class MachineResource { MachineResource
@Path("{id}/softwares")
public SoftwareResource softwares(@PathParam("id") Long id) {
Machine machine = new MachineRepository().retrieve(id);
if (machine != null) {
SoftwareResource softwareResource = new SoftwareResource();
softwareResource.setMachine(machine);
return softwareResource;
}
throw new WebApplicationException(404);
}
@POST @Consumes("application/xml")
public Response create(Machine machine) {
Long id = new MachineRepository().save(machine);
return Response.created(UriBuilder.fromPath("/" + id).build()).build();
}
@GET @Path("{id}")
@Produces("application/xml")
public Machine show(@PathParam("id") Long id) {
return new MachineRepository().retrieve(id);
}
@GET
@Produces("application/xml")
public Machines list() {
Machines machines = new Machines();
machines.setMachine(new MachineRepository().list());
return machines;
147. @Path("/machines")
public class MachineResource { MachineResource
@Path("{id}/softwares")
public SoftwareResource softwares(@PathParam("id") Long id) {
Machine machine = new MachineRepository().retrieve(id);
if (machine != null) {
SoftwareResource softwareResource = new SoftwareResource();
softwareResource.setMachine(machine);
return softwareResource;
}
throw new WebApplicationException(404);
}
@POST @Consumes("application/xml")
public Response create(Machine machine) {
Long id = new MachineRepository().save(machine);
return Response.created(UriBuilder.fromPath("/" + id).build()).build();
}
@GET @Path("{id}")
@Produces("application/xml")
public Machine show(@PathParam("id") Long id) {
return new MachineRepository().retrieve(id);
}
@GET
@Produces("application/xml")
public Machines list() {
Machines machines = new Machines();
machines.setMachine(new MachineRepository().list());
return machines;
157. 1. conventions?
@Path("/services")
public class Services {
@GET
public Response services(
@QueryParam("action") String action) {
ServiceFactory factory = new ServiceFactory();
Service service = factory.getServiceFor(action);
return service.execute();
}
}
158. Convention over Configuration
@Resource
public class Services {
private final ServiceFactory factory;
public Services(ServiceFactory factory) {
this.factory = factory;
}
public void services(String action) {
factory.getServiceFor(action).execute();
}
}
162. 2. TDD: hard to test
@Path("/products")
public class Products {
coupled to the
@GET implementation
public Response create(
@QueryParam("what") String what) {
// persists
return Response.ok()
.type("application/xml")
.entity("<product>...</product>")
.build();
}
}
163. TDD: mock it
coupled to the interface
couple--
@Resource
public class Services {
private final Response response;
public Services(Response response) {
this.response = response;
}
public void services(String action) {
response.getServiceFor(action).execute();
}
}
164. TDD: mock it
coupled to the interface
couple--
@Resource
public class Services {
private final Response response;
public Services(Response response) {
this.response = response;
}
public void services(String action) {
response.getServiceFor(action).execute();
}
}
165. 3. Content negotiation by hand
@Path("/softwares")
public class SoftwareResource {
@POST @Consumes("application/xml")
public Response install(Software software) {
software = SoftwareRepository.register(software);
long id = software.getId();
URI uri = UriBuilder.fromPath("/softwares/" + id)
.build();
software.install();
return Response.created(uri).build();
}
166. Let us do it for you.
@Resource
public class SoftwareResource {
@Post @Consumes
public void install(Software software) {
software = SoftwareRepository.register(software);
response.created(software);
}
}
167. Let us do it for you.
@Resource
public class SoftwareResource {
@Post @Consumes
public void install(Software software) {
software = SoftwareRepository.register(software);
response.created(software);
}
}
168. 4. URI coupling
writing the URI once
...
@GET @Path("/softwares/{id}")
public Response install(@QueryParam("id") Software
software) {
// ...
}
169. 4. URI coupling
writing the URI again
several times
@Path("/softwares")
public class SoftwareResource {
@POST @Consumes("application/xml")
public Response install(Software software) {
software = SoftwareRepository.register(software);
long id = software.getId();
URI uri = UriBuilder.fromPath("/softwares/" + id)
.build();
software.install();
return Response.created(uri).build();
}
170. 4. URI coupling
code
@Path("/softwares")
public class SoftwareResource {
@POST @Consumes("application/xml")
public Response install(Software software) {
software = SoftwareRepository.register(software);
long id = software.getId();
URI uri = UriBuilder.fromPath("/softwares/" + id)
.build();
software.install();
return Response.created(uri).build();
}
171. ZERO uri replication
@Resource
public class SoftwareResource {
@Post @Consumes
public void install(Software software) {
// ...
response.use(SoftwareResource.class).show(software);
}
}
172. ZERO uri replication
@Resource
public class SoftwareResource {
@Post @Consumes
public void install(Software software) {
// ...
response.use(SoftwareResource.class).show(software);
}
}
173. 5. Parameter list
@Path("/machines")
public class MachineResource {
@Path("{id}/softwares")
public SoftwareResource softwares(@PathParam("id") Long id) {
Machine machine = new MachineRepository().retrieve(id);
if (machine == null) {
throw new WebApplicationException(404);
}
// ...
}
}
174. Yes, we can do it.
@Resource
public class MachineResource {
@Post ("{m.id}/softwares")
public SoftwareResource softwares(Machine m) {
Machine machine = new MachineRepository().retrieve(m
// ...
}
}
parameter converter chain of responsability
175. Yes, we can do it.
@Resource
public class MachineResource {
@Post ("{m.id}/softwares")
public SoftwareResource softwares(Machine m) {
Machine machine = new MachineRepository().retrieve(m
// ...
}
}
parameter converter chain of responsability
178. Response response = client.at
("http://localhost:9998/user/574").get();
User user = response.getResource();
System.out.println("user: " + user.getName());
6. Client internal DSLs
179. User user = response.getResource();
System.out.println("user: " + user.getName());
Link link = resource(user).getLink("machine");
response = link.follow().post(new Machine());
180. Link link = resource(user).getLink("machine");
response = link.follow().post(new Machine());
double amount = resource(user).refresh().
getAmountDue();
181. double amount = resource(user).refresh().
getAmountDue();
link = resource(user).getLink("payment");
Payment payment = new Payment(amount);
response = link.follow().post(payment);
183. link = resource(user).getLink("payment");
Payment payment = new Payment(amount);
response = link.follow().post(payment);
System.out.println("payment completed");
i was looking for a DSL
and i did not know it!
184. bottom up
design by committe
mime type?
microformato
controlled vocabulary
191. Further reading
Roy Fielding dissertation
Rest in Practice, Jim Webber and others
Restful Webservices Cookbook, Subbu Allamaraju
192. Further reading
Roy Fielding dissertation
Rest in Practice, Jim Webber and others
Restful Webservices Cookbook, Subbu Allamaraju
Restful Web Services, Richardson and Ruby
193. Further reading
Roy Fielding dissertation
Rest in Practice, Jim Webber and others
Restful Webservices Cookbook, Subbu Allamaraju
Restful Web Services, Richardson and Ruby
JAX-RS specification
194. Further reading
Roy Fielding dissertation
Rest in Practice, Jim Webber and others
Restful Webservices Cookbook, Subbu Allamaraju
Restful Web Services, Richardson and Ruby
JAX-RS specification
Infoq articles on REST
195. Further reading
Roy Fielding dissertation
Rest in Practice, Jim Webber and others
Restful Webservices Cookbook, Subbu Allamaraju
Restful Web Services, Richardson and Ruby
JAX-RS specification
Infoq articles on REST
Restfulie guide
197. Interviews and
Presentations
Stefan Tilkov interview on InfoQ
198. Interviews and
Presentations
Stefan Tilkov interview on InfoQ
http://bit.ly/9RUXKL
199. Interviews and
Presentations
Stefan Tilkov interview on InfoQ
http://bit.ly/9RUXKL
Leonard Richardson’s presentation at QCon
200. Interviews and
Presentations
Stefan Tilkov interview on InfoQ
http://bit.ly/9RUXKL
Leonard Richardson’s presentation at QCon
http://bit.ly/dj2W66
201. Interviews and
Presentations
Stefan Tilkov interview on InfoQ
http://bit.ly/9RUXKL
Leonard Richardson’s presentation at QCon
http://bit.ly/dj2W66
Martin Fowler on REST
202. Interviews and
Presentations
Stefan Tilkov interview on InfoQ
http://bit.ly/9RUXKL
Leonard Richardson’s presentation at QCon
http://bit.ly/dj2W66
Martin Fowler on REST
http://bit.ly/bx61ci
204. Interviews and
Presentations
Ian Robinson and Jim Webber interview
205. Interviews and
Presentations
Ian Robinson and Jim Webber interview
http://bit.ly/aEuzj3
206. Interviews and
Presentations
Ian Robinson and Jim Webber interview
http://bit.ly/aEuzj3
Jan Algermissen classification
207. Interviews and
Presentations
Ian Robinson and Jim Webber interview
http://bit.ly/aEuzj3
Jan Algermissen classification
http://bit.ly/cycFBF
208. Interviews and
Presentations
Ian Robinson and Jim Webber interview
http://bit.ly/aEuzj3
Jan Algermissen classification
http://bit.ly/cycFBF
Guilherme Silveira on REST clients
209. Interviews and
Presentations
Ian Robinson and Jim Webber interview
http://bit.ly/aEuzj3
Jan Algermissen classification
http://bit.ly/cycFBF
Guilherme Silveira on REST clients
http://bit.ly/aHCglv